package ac.github.oa.util

import ac.github.oa.api.common.script.InlineScriptContext
import ac.github.oa.api.common.script.StringScript
import ac.github.oa.internal.core.item.random.RandomPlant
import taboolib.common.platform.function.isPrimaryThread
import taboolib.common.platform.function.submit
import taboolib.platform.BukkitPlugin
import java.io.File
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type

fun newfolder(root: File, name: String, files: List<String>): File {
    val file = File(root, name)
    if (!file.exists()) {
        file.mkdirs()
        files.forEach { saveDefaultFile(file, it) }
    }
    return file
}


fun File.listFile(suffix: String = ""): List<File> {
    val listOf = arrayListOf<File>()
    this.listFiles()?.forEach {
        if (it.isDirectory) {
            listOf.addAll(it.listFile(suffix))
        } else {
            if (suffix == "" || it.name.endsWith(".$suffix")) {
                listOf.add(it)
            }
        }
    }
    return listOf
}

fun any(list: List<String>, keyword: List<String>) = list.any { keyword.any { s -> it.contains(s) } }

fun saveDefaultFile(file: File, name: String) {
    BukkitPlugin.getInstance().saveResource("${file.name}/$name", false)
}

fun String.rebuild(): List<String> {
    if (this.contains("/n")) {
        return this.split("/n")
    }
    return listOf(this)
}

fun List<String>.rebuild(): List<String> {
    val listOf = arrayListOf<String>()
    this.forEach {
        listOf.addAll(it.rebuild())
    }
    return listOf
}

fun Any.random(context: InlineScriptContext): String {
    return toString().random(context)
}

fun String.random(context: InlineScriptContext): String {
    return RandomPlant.eval(this, context)
}

fun List<String>.random(context: InlineScriptContext): List<String> {
    return StringScript.parse(this, context).filter { !it.contains("%del%") }
}


fun getInterfaceT(o: Any, index: Int): Class<*>? {
    val types = o.javaClass.genericInterfaces
    val parameterizedType = types[index] as ParameterizedType
    val type = parameterizedType.actualTypeArguments[index]
    return checkType(type, index)
}

private fun checkType(type: Type?, index: Int): Class<*>? {
    return when (type) {
        is Class<*> -> {
            type
        }

        is ParameterizedType -> {
            val t = type.actualTypeArguments[index]
            checkType(t, index)
        }

        else -> {
            val className = if (type == null) "null" else type.javaClass.name
            throw IllegalArgumentException(
                "Expected a Class, ParameterizedType"
                        + ", but <" + type + "> is of type " + className
            )
        }
    }
}

fun sync(func: () -> Unit) {
    if (isPrimaryThread) {
        func()
    } else {
        submit { func() }
    }
}

